package com.itheima.service.Impl;

import com.itheima.mapper.*;
import com.itheima.pojo.Setmeal;
import com.itheima.pojo.SetmealNews;
import com.itheima.pojo.vo.BusinessVo;
import com.itheima.pojo.vo.HotSetmealVo;
import com.itheima.pojo.vo.MemberVo;
import com.itheima.pojo.vo.SetmealVo;
import com.itheima.service.ReportService;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.text.DecimalFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

@Service
@Slf4j
public class ReportServiceImpl implements ReportService {
    @Autowired
    private ReportMapper reportMapper;
    @Autowired
    private SetmealMapper setmealMapper;
    @Autowired
    private OrderrMapper orderMapper;
    @Autowired
    private VippMapper vippMapper;
    /**
     * 会员数量统计
     * @return
     */
    @Override
    public MemberVo getMemberReport() {
        MemberVo memberVo =new MemberVo();
        LocalDate now = LocalDate.now();
        now = now.minusYears(1);
        List<LocalDate> monthDays = new ArrayList<>();
        List<String> monthStrs = new ArrayList<>();
        for (int i = 1; i <= 12; i++) {
            //判断当前是否为本月最后一天
            if(now.getDayOfMonth() == now.lengthOfMonth()){
                    monthDays.add(now);
                    monthStrs.add(now+"");
                    now = now.plusMonths(1);
               
            }else {
                    //获取当前月的最后一天
                    LocalDate lastDay = now.withDayOfMonth(now.lengthOfMonth());
                    monthDays.add(lastDay);
                    monthStrs.add(lastDay+"");
                    now = now.plusMonths(1);
            }
        }
        log.info("会员数量统计：{}",monthDays);

        List<Integer> memberCounts = new ArrayList<>();
        for (LocalDate monthDay : monthDays) {
           Integer memberCount = reportMapper.getMemberReport(monthDay);
           memberCount = memberCount == null ? 0 : memberCount;
           memberCounts.add(memberCount);
        }

        memberVo.setMemberCount(memberCounts);
        memberVo.setMonths(monthStrs);
        return memberVo;
    }



    /**
     * 获取套餐占比统计数据
     * @return
     */
    @Override
    public SetmealVo getSetmealReport() {
        SetmealVo setmealVo = new SetmealVo();
        List<Setmeal> setmealList = setmealMapper.getAll();
        //获取套餐名称
        List<String> setmealNames = setmealList.stream().map(Setmeal::getName).collect(Collectors.toList());
        //获取套餐id
        List<Integer> setmealId = setmealList.stream().map(Setmeal::getId).collect(Collectors.toList());


        List<SetmealNews> list = new ArrayList<>();

        for (int i = 0; i < setmealId.size(); i++) {
            SetmealNews setmealNews = new SetmealNews();
            Integer count = orderMapper.getById(setmealId.get(i));
            count= count == null ? 0 : count;
            //设置套餐名称和数量
            setmealNews.setName(setmealNames.get(i));
            setmealNews.setValue(count);
            //添加到集合中
            list.add(setmealNews);
        }
        setmealVo.setSetmealNames(setmealNames);
        setmealVo.setSetmealCounts(list);
        return setmealVo;
    }

    /**
     * 获取运营数据统计
     * @return
     */
    @Override
    public BusinessVo getBusinessReportData() {
        BusinessVo businessVo = new BusinessVo();
        //获取当前时间
        LocalDateTime now = LocalDateTime.now();
        //获取今日的开始时间
        LocalDateTime begin = now.withHour(0).withMinute(0).withSecond(0);
        //获取本周第一天的开始时间
        LocalDateTime weekBegin = now.with(java.time.temporal.TemporalAdjusters.previousOrSame(java.time.DayOfWeek.MONDAY))
                .withHour(0).withMinute(0).withSecond(0);
        //获取本月第一天
        LocalDateTime monthBegin = now.withDayOfMonth(1).withHour(0).withMinute(0).withSecond(0);
        log.info("今日开始时间：{},{},{}",begin,weekBegin,monthBegin);
        //设置今日，本周，本月新增会员数和总会员数
        businessVo.setTodayNewMember(vippMapper.getByTime(begin,now)==null?0:vippMapper.getByTime(begin,now));
        businessVo.setThisWeekNewMember(vippMapper.getByTime(weekBegin,now)==null?0:vippMapper.getByTime(weekBegin,now));
        businessVo.setThisMonthNewMember(vippMapper.getByTime(monthBegin,now)==null?0:vippMapper.getByTime(monthBegin,now));
        businessVo.setTotalMember(vippMapper.getByTime(null,now)==null?0:vippMapper.getByTime(null,now));

        Map map = new HashMap<>();
        map.put("begin",begin);
        map.put("end",now);
        map.put("orderStatus",null);
        //设置今日，本周，本月的预约数
        businessVo.setTodayOrderNumber(orderMapper.getByMap(map)==null?0:orderMapper.getByMap(map));
        map.put("begin",weekBegin);
        businessVo.setThisWeekOrderNumber(orderMapper.getByMap(map)==null?0:orderMapper.getByMap(map));
        map.put("begin",monthBegin);
        businessVo.setThisMonthOrderNumber(orderMapper.getByMap(map)==null?0:orderMapper.getByMap(map));

        //设置今日，本周，本月的到诊数
        map.put("orderStatus","已到诊");
        map.put("begin",begin);
        businessVo.setTodayVisitsNumber(orderMapper.getByMap(map)==null?0:orderMapper.getByMap(map));
        map.put("begin",weekBegin);
        businessVo.setThisWeekVisitsNumber(orderMapper.getByMap(map)==null?0:orderMapper.getByMap(map));
        map.put("begin",monthBegin);
        businessVo.setThisMonthVisitsNumber(orderMapper.getByMap(map)==null?0:orderMapper.getByMap(map));
        businessVo.setReportDate(LocalDate.from(now));

        //设置热门套餐

       Integer total =orderMapper.getTotal();
        List<HotSetmealVo> hotSetmealVos = orderMapper.getHotSetmeal();
        for (HotSetmealVo hotSetmealVo : hotSetmealVos) {
            //计算占比并保留4位小数切类型为double
            hotSetmealVo.setProportion(hotSetmealVo.getSetmealCount()/total+0.0);

        }
        businessVo.setHotSetmeal(hotSetmealVos);
        return businessVo;
    }

    /**
     * 导出运营数据统计
     */
    @Override
    public void exportBusinessReport(HttpServletResponse response) throws IOException {
        //创建一个输入流
        InputStream in = this.getClass().getClassLoader().getResourceAsStream("templates/report_template.xlsx");
        //获取当前时间
        LocalDateTime now = LocalDateTime.now();

        //获取今日的开始时间
        LocalDateTime begin = now.withHour(0).withMinute(0).withSecond(0);
        //获取本周第一天的开始时间
        LocalDateTime weekBegin = now.with(java.time.temporal.TemporalAdjusters.previousOrSame(java.time.DayOfWeek.MONDAY))
                .withHour(0).withMinute(0).withSecond(0);
        //获取本月第一天
        LocalDateTime monthBegin = now.withDayOfMonth(1).withHour(0).withMinute(0).withSecond(0);
        XSSFWorkbook workbook = null;
        try {
            workbook = new XSSFWorkbook(in);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        XSSFSheet sheet = workbook.getSheetAt(0);
        //设置今日，本周，本月新增会员数和总会员数
        sheet.getRow(2).getCell(5).setCellValue(LocalDate.from(now).toString());
        sheet.getRow(4).getCell(5).setCellValue(vippMapper.getByTime(begin,now)==null?0:vippMapper.getByTime(begin,now));
        sheet.getRow(4).getCell(7).setCellValue(vippMapper.getByTime(null,now)==null?0:vippMapper.getByTime(null,now));
        sheet.getRow(5).getCell(5).setCellValue(vippMapper.getByTime(weekBegin,now)==null?0:vippMapper.getByTime(weekBegin,now));
        sheet.getRow(5).getCell(7).setCellValue(vippMapper.getByTime(monthBegin,now)==null?0:vippMapper.getByTime(monthBegin,now));

        Map map = new HashMap<>();
        map.put("begin",begin);
        map.put("end",now);
        map.put("orderStatus",null);
        //设置今日，本周，本月的预约数
        sheet.getRow(7).getCell(5).setCellValue(orderMapper.getByMap(map)==null?0:orderMapper.getByMap(map));
        map.put("begin",weekBegin);
        sheet.getRow(8).getCell(5).setCellValue(orderMapper.getByMap(map)==null?0:orderMapper.getByMap(map));
        map.put("begin",monthBegin);
        sheet.getRow(9).getCell(5).setCellValue(orderMapper.getByMap(map)==null?0:orderMapper.getByMap(map));

        //设置今日，本周，本月的到诊数
        map.put("orderStatus","已到诊");
        map.put("begin",begin);
        sheet.getRow(7).getCell(7).setCellValue(orderMapper.getByMap(map)==null?0:orderMapper.getByMap(map));
        map.put("begin",weekBegin);
        sheet.getRow(8).getCell(7).setCellValue(orderMapper.getByMap(map)==null?0:orderMapper.getByMap(map));
        map.put("begin",monthBegin);
        sheet.getRow(9).getCell(7).setCellValue(orderMapper.getByMap(map)==null?0:orderMapper.getByMap(map));

        Integer total =orderMapper.getTotal();
        List<HotSetmealVo> hotSetmealVos = orderMapper.getHotSetmeal();
        for (HotSetmealVo hotSetmealVo : hotSetmealVos) {
            //计算占比并保留4位小数切类型为double
            hotSetmealVo.setProportion(hotSetmealVo.getSetmealCount()/total*100+0.0);
        }
        for (int i = 0; i < hotSetmealVos.size(); i++) {
            sheet.getRow(12+i).getCell(4).setCellValue(hotSetmealVos.get(i).getName());
            sheet.getRow(12+i).getCell(5).setCellValue(hotSetmealVos.get(i).getSetmealCount());
            sheet.getRow(12+i).getCell(6).setCellValue(hotSetmealVos.get(i).getProportion()+"%");
        }
        ServletOutputStream out = response.getOutputStream();
        response.setContentType("application/vnd.ms-excel");
        response.setHeader("content-Disposition", "attachment;filename=report.xlsx");
        workbook.write(out);
        workbook.close();
        out.close();
    }
}
